//
//  PublicObj.m
//  Bullet
//
//  Created by  on 2019/8/12.
//  Copyright © 2019 . All rights reserved.
//

#import "PublicObj.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#import <sys/utsname.h>
///获取设备唯一标识的库
#import <AdSupport/AdSupport.h>
#import "FCUUID.h"

@implementation PublicObj

#pragma mark - 根据色值获取图片
+(UIImage*)getImgWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f,0.0f, 1.0f,1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context =UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}


#pragma mark 头像选择
+ (NSString *)defaultHead:(int)sex userid:(int)userid {
    NSString *place = @"default_head";
    if (sex == 1) {
        if (userid % 2 == 0) {
            place = @"ic_head_man_0";
        }else{
            place = @"ic_head_man_1";
        }
    }else{
        if (userid % 2 == 0) {
            place = @"ic_head_woman_0";
        }else{
            place = @"ic_head_woman_1";
        }
    }
    return place;
    
}
#pragma mark 时间格式化
+(NSString *)getTimeShow:(float)time{
    NSString * str = [NSMutableString new];
    int m = 0;
    int s = 0;
    m = time/60;
    if (m<10) {
        str = [str stringByAppendingFormat:@"0%d",m];
    }else{
        str = [str stringByAppendingFormat:@"%d",m];
    }
    s = (int)time%60;
    if (s<10) {
        str = [str stringByAppendingFormat:@":0%d",s];
    }else{
        str = [str stringByAppendingFormat:@":%d",s];
    }
    return str;
}
#pragma mark 获取当前时间戳
+(NSString *)getNowTimeTimestamp{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    //设置时区,这个对于时间的处理有时很重要
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    [formatter setTimeZone:timeZone];
    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
    return timeSp;
}
#pragma mark 获取两个值之间的随机数
+(int)getRandomNumber:(int)from to:(long)to
{
    return (int)(from + (arc4random() % (to - from + 1)));
}
#pragma mark 请求参数加密
+ (id)reqeustHandleParams:(NSDictionary *)params{
    NSDictionary *jiamiDic = [self getNeedSignStrFrom:params];
    return jiamiDic;
}
#pragma mark - 以下是加密方式处理
/*
 字典key排序
 */
+ (NSDictionary *)getNeedSignStrFrom:(NSDictionary *)dic{
    if (dic == nil || ![dic isKindOfClass:[NSDictionary class]] || dic.count == 0) return @{};
    NSString * time = [NSString stringWithFormat:@"%@%u%u",[PublicObj getNowTimeTimestamp],[PublicObj getRandomNumber:1000 to:1000000],[PublicObj getRandomNumber:1000 to:1000000]];
    NSMutableDictionary *dictTmp = [[NSMutableDictionary alloc] init];
    if (dic && dic.count) {
        [dictTmp addEntriesFromDictionary:dic];
    }
    [dictTmp setObject:time forKey:@"timestamp"];
    [dictTmp setObject:QZAPPVersion forKey:@"levelno"];
    NSArray *arrPrimary = dictTmp.allKeys;
    NSMutableDictionary *tmpAllInfo = [NSMutableDictionary dictionary];
    for ( int i=0; i<arrPrimary.count; i++) {
        NSString *key = [NSString stringWithFormat:@"%@",arrPrimary[i]];
        id value = dictTmp[key];
//        NSLog(@"%@--%@",value, key);
        NSString *tmpValue = [NSString stringWithFormat:@"%@",value];
        if (tmpValue) {
            [tmpAllInfo setObject:value forKey:key];
        }
    }
    NSArray *arrKey = [tmpAllInfo.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
        NSComparisonResult result = [obj1 compare:obj2];
        return result==NSOrderedDescending;//NSOrderedAscending 倒序
    }];
    NSString*str = @"";
    for (NSString *s in arrKey) {
        id value = tmpAllInfo[s];
//        NSLog(@"%@--%@",value, s);
        if([value isKindOfClass:[NSDictionary class]]) {
            value = [self getNeedSignStrFrom:value];
        }
        if([str length] !=0) {
            str = [str stringByAppendingString:@"&"];
        }
        str = [str stringByAppendingFormat:@"%@=%@",s,value];
    }
    str = [NSString stringWithFormat:@"%@%@",str,QZ_ENCRYPTIONKEY];
    NSMutableDictionary *allDic = [NSMutableDictionary dictionary];
    [allDic addEntriesFromDictionary:dictTmp];
    [allDic setObject:time forKey:@"timestamp"];
    [allDic setObject:[self md5:str] forKey:@"sign"];
//    [allDic setObject:@"88888888" forKey:@"sign"];
    return allDic;
}
/*
 MD5加密
 */
+ (NSString *)md5:(NSString *)string{
    const char *cStr = [string UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02X", digest[i]];
    }
    return result;
}
#pragma mark 请求头组装
+ (NSDictionary *)getNetworkingHeaders{
    NSMutableDictionary *headers = [NSMutableDictionary new];
    [headers setObject:QZAPPVersion forKey:@"levelno"];
    [headers setObject:[NSString stringWithFormat:@"%@-%.2f",KISIPAD?@"iPad":@"iPhone",[[[UIDevice currentDevice] systemVersion]  floatValue]] forKey:@"deviceno"];
    [headers setObject:[self identifier] forKey:@"deviceid"];

    if([QZUserInfoModel isLogin]){
        if([QZUserInfoModel share].token){
            [headers setObject:[QZUserInfoModel share].token forKey:@"token"];
        }
        if([QZUserInfoModel share].mid){
            [headers setValue:[NSString stringWithFormat:@"%@",[QZUserInfoModel share].mid] forKey:@"userid"];
        }
    }
    return headers;
}
+ (NSString *)identifier {
    return [FCUUID uuidForDevice];
}
#pragma mark 请求数据解密
+ (NSDictionary *)responseDataWithAES:(id)responseObject{
    NSData *utf8encoding = [self dataFromBase64String:responseObject];
    NSString *str = @"";
    if (utf8encoding != nil ) {
        str = [[NSString alloc] initWithData:utf8encoding encoding:NSUTF8StringEncoding];
    }
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];

    NSString *ivStr = jsonDict[@"iv"];
    NSData * ivencoding = [self dataFromBase64String:ivStr];
    NSString *iv = @"";
    if (ivencoding != nil ) {
        iv = [[NSString alloc] initWithData:ivencoding encoding:NSUTF8StringEncoding];
    }
    NSString *valueStr = [self aci_decryptWithAESWithValue:jsonDict[@"value"] iv:iv];
    NSDictionary *valueDict = [NSJSONSerialization JSONObjectWithData:[valueStr dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
    
    return valueDict;
}
//AES解密
+ (NSString*)aci_decryptWithAESWithValue:(NSString*)value iv:(NSString*)ivStr{
    if (value != nil && [value isKindOfClass:[NSString class]] && value.length != 0 && ivStr != nil && [ivStr isKindOfClass:[NSString class]]) {
        NSData *baseData = [[NSData alloc]initWithBase64EncodedString:value options:0];
        NSData *AESData = [self AES128operation:kCCDecrypt
                                           data:baseData
                                            key:QZ_DECRYPTIONKEY
                                             iv:ivStr];
        NSString *decStr = [[NSString alloc] initWithData:AESData encoding:NSUTF8StringEncoding];
        return decStr;
    }
    return @"";
}

+(NSData *)dataFromBase64String:(NSString *)encoding
{
    if (encoding == nil || ![encoding isKindOfClass:[NSString class]] ) {
        return nil;
    }
    NSData *data = nil;
    unsigned char *decodedBytes = NULL;
    @try {
#define __ 255
        static char decodingTable[256] = {
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x00 - 0x0F
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x10 - 0x1F
            __,__,__,__, __,__,__,__, __,__,__,62, __,__,__,63,  // 0x20 - 0x2F
            52,53,54,55, 56,57,58,59, 60,61,__,__, __, 0,__,__,  // 0x30 - 0x3F
            __, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,  // 0x40 - 0x4F
            15,16,17,18, 19,20,21,22, 23,24,25,__, __,__,__,__,  // 0x50 - 0x5F
            __,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,  // 0x60 - 0x6F
            41,42,43,44, 45,46,47,48, 49,50,51,__, __,__,__,__,  // 0x70 - 0x7F
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x80 - 0x8F
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0x90 - 0x9F
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xA0 - 0xAF
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xB0 - 0xBF
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xC0 - 0xCF
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xD0 - 0xDF
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xE0 - 0xEF
            __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__,  // 0xF0 - 0xFF
        };
        encoding = [encoding stringByReplacingOccurrencesOfString:@"=" withString:@""];
        NSData *encodedData = [encoding dataUsingEncoding:NSASCIIStringEncoding];
        unsigned char *encodedBytes = (unsigned char *)[encodedData bytes];
        
        NSUInteger encodedLength = [encodedData length];
        if( encodedLength >= (NSUIntegerMax - 3) ) return nil; // NSUInteger overflow check
        NSUInteger encodedBlocks = (encodedLength+3) >> 2;
        NSUInteger expectedDataLength = encodedBlocks * 3;
        
        unsigned char decodingBlock[4];
        
        decodedBytes = malloc(expectedDataLength);
        if( decodedBytes != NULL ) {
            
            NSUInteger i = 0;
            NSUInteger j = 0;
            NSUInteger k = 0;
            unsigned char c;
            while( i < encodedLength ) {
                c = decodingTable[encodedBytes[i]];
                i++;
                if( c != __ ) {
                    decodingBlock[j] = c;
                    j++;
                    if( j == 4 ) {
                        decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);
                        decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);
                        decodedBytes[k+2] = (decodingBlock[2] << 6) | (decodingBlock[3]);
                        j = 0;
                        k += 3;
                    }
                }
            }
            
            // Process left over bytes, if any
            if( j == 3 ) {
                decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);
                decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);
                k += 2;
            } else if( j == 2 ) {
                decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);
                k += 1;
            }
            data = [[NSData alloc] initWithBytes:decodedBytes length:k];
        }
    }
    @catch (NSException *exception) {
        data = nil;
        //        NSLog(@"WARNING: error occured while decoding base 32 string: %@", exception);
    }
    @finally {
        if( decodedBytes != NULL ) {
            free( decodedBytes );
        }
    }
    return data;
}

/**
 *  AES加解密算法
 *
 *  @param operation kCCEncrypt（加密）kCCDecrypt（解密）
 *  @param data      待操作Data数据
 *  @param key       key
 *  @param iv        向量
 *
 */
+ (NSData *)AES128operation:(CCOperation)operation data:(NSData *)data key:(NSString *)key iv:(NSString *)iv {
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    // IV
    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    size_t bufferSize = [data length] + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    
    CCCryptorStatus cryptorStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                            keyPtr, kCCKeySizeAES128,
                                            ivPtr,
                                            [data bytes], [data length],
                                            buffer, bufferSize,
                                            &numBytesEncrypted);
    
    if(cryptorStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    } else {
        NSLog(@"Error");
    }
    
    free(buffer);
    return nil;
}
@end
